package client.ftp;

import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPException;
import it.sauronsoftware.ftp4j.FTPIllegalReplyException;
import java.io.IOException;
/**
 * the following imports are only for security
 */ 
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * This class handles connections via FTPS. It extends the FTPHandler. 
 * It uses most of the methods of FTPHandler. The only override is (logically)
 * for the connect method.
 * @author Robert
 */
public class FTPSHandler extends FTPHandler {
    
    /**
     * The sole constructor.
     * @param hostname the name of the server to connect to (IP address or domain name)
     * @param username the user name of the account
     * @param password the password of the account
     * @param port the port number to connect to
     */
    public FTPSHandler(String hostname, String username, String password, int port) {
        super(hostname, username, password, port);
        this.client = new FTPClient();
    }
    
    /**
     * Opens a connection to an FTP server with SSL enabled.
     * @return An integer (0=Success,1=IllegalStateException,2=IOException,3=FTPIllegalReplyException,4=FTPException)
     * @throws IllegalStateException
     * @throws IOException
     * @throws FTPIllegalReplyException
     * @throws FTPException
     */
    @Override
    protected int connect() {
        try {            
            /**
             * The following code allows for every client certificate to be 
             * trusted. This, however is not advisable. In practice clients
             * should install their own certificates and create public/private 
             * key pairs!
             */
            TrustManager[] trustManager = new TrustManager[]{new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() { return null; }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {}
            public void checkServerTrusted(X509Certificate[] certs, String authType) {}
            }};
            SSLContext sslContext = null;
            try {
                sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, trustManager, new SecureRandom());
            } catch (NoSuchAlgorithmException ex) {
                printError(ex);
            } catch (KeyManagementException ex) {
                printError(ex);
            }
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            client.setSSLSocketFactory(sslSocketFactory);
            client.setSecurity(FTPClient.SECURITY_FTPES);
            /*****************************************************************/            
              
            client.connect(hostname,port);
            printMessage("Connected to " + hostname + " at port " + port +" using FTPS");
        } catch (IllegalStateException ex) {
            printError(ex);
            return 1;
        } catch (IOException ex) {
            printError(ex);
            return 2;
        } catch (FTPIllegalReplyException ex) {
            printError(ex);
            return 3;
        } catch (FTPException ex) {
            printError(ex);
            return 4;
        }
        return 0;
    }
}
